
#include"sphere.h"
#include"ray.h"
#include"algfloat.h"
#include<math.h>
#include<stdio.h>

bool Sphere::Hit (Ray * ray)
{
  bool shadow = ray->shadow_mode;
  int level = shadow?SHADOW_RAY:VIEW_RAY;
  float * p = ray->GetP(level);
  float * d = ray->GetD(level);
  float temp[4];
  AFSub(p, vpos, temp);
  float a = AFDot(d,d);
  float b = 2*AFDot(d, temp);
  float c = AFDot(temp,temp) - radius*radius;
  float delta = b*b - 4*a*c;
  if(delta<0)
    return false;
  float t = (-b-sqrt(delta))/(2*a);
  //printf("shadow %s\n",shadow?"true":"false");
  if(shadow){
    if(t<=ray->tmax && t>=0.0){
      //printf("SPH shadow id=%d t=%f tmax=%f ret=%s tmin=%f obj=%d\n",ray->id,t, ray->tmax, t<=ray->tmax?"true":"false",ray->tmin,ray->shadow_obj);
      return true;
    }
    return false;
  }
  //printf("Chegou\n");
  if(t<ray->tmin || ray->tmin==-1.0){
    //printf("SPH id=%d t=%f tmin=%f\n",ray->id,t, ray->tmin);
    float * ps = ray->GetP(SHADOW_RAY); 
    ray->CalcPoint(VIEW_RAY,t,ps);
    float * normal = ray->normal;
    //normal = (ps-vpos)/radius
    normal[0] = (ps[0] - vpos[0])/radius;
    normal[1] = (ps[1] - vpos[1])/radius;
    normal[2] = (ps[2] - vpos[2])/radius;
    normal[3] = 0.0;
    ray->tmin = t;
    SetRayAtt(ray);
    return true;
  }
  return false;
}

void Sphere::SetViewPos (float * mat)
{
  AFMatXVec(mat,wpos,vpos);
}
